package com.qst.controller;

import com.qst.pojo.vo.InventoryHistoryVO;
import com.qst.pojo.vo.StationInventoryVO;
import com.qst.pojo.entity.InventoryHistory;
import com.qst.pojo.entity.Station;
import com.qst.pojo.entity.StationInventory;
import com.qst.pojo.entity.User;
import com.qst.pojo.entity.Order;
import com.qst.repository.InventoryHistoryRepository;
import com.qst.repository.OrderRepository;
import com.qst.repository.StationInventoryRepository;
import com.qst.repository.StationRepository;
import com.qst.repository.UserRepository;
import com.qst.util.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 站点控制器
 */
@RestController
@RequestMapping("/api/stations")
public class StationController {

    private static final Logger logger = LoggerFactory.getLogger(StationController.class);

    @Autowired
    private StationRepository stationRepository;

    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private StationInventoryRepository stationInventoryRepository;
    
    @Autowired
    private InventoryHistoryRepository inventoryHistoryRepository;
    
    @Autowired
    private OrderRepository orderRepository;

    /**
     * 获取站点列表（分页）
     */
    @GetMapping
    public Result<Map<String, Object>> getStationList(
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "20") Integer pageSize,
            @RequestParam(required = false) String keyword,
            @RequestParam(required = false) String status,
            @RequestParam(required = false) Integer managerId
    ) {
        try {
            // 创建分页对象
            Pageable pageable = PageRequest.of(page - 1, pageSize, Sort.by(Sort.Direction.DESC, "id"));

            // 处理空字符串为null
            String keywordFilter = (keyword != null && keyword.trim().isEmpty()) ? null : keyword;
            Station.StationStatus statusFilter = null;
            if (status != null && !status.trim().isEmpty()) {
                try {
                    statusFilter = Station.StationStatus.valueOf(status);
                } catch (IllegalArgumentException e) {
                    logger.warn("无效的状态值: {}", status);
                }
            }

            // 根据条件查询站点列表
            Page<Station> stationPage = stationRepository.findByConditions(keywordFilter, statusFilter, managerId, pageable);

            // 填充管理员名称和电话
            List<Station> stations = stationPage.getContent();
            for (Station station : stations) {
                if (station.getManagerId() != null) {
                    userRepository.findById(station.getManagerId()).ifPresent(user -> {
                        station.setManagerName(user.getRealName());
                        station.setManagerPhone(user.getPhone());
                    });
                }
            }

            // 构建返回数据
            Map<String, Object> data = new HashMap<>();
            data.put("list", stations);
            data.put("total", stationPage.getTotalElements());
            data.put("page", page);
            data.put("pageSize", pageSize);

            return Result.success(data);
        } catch (Exception e) {
            logger.error("获取站点列表失败", e);
            return Result.error("获取站点列表失败");
        }
    }

    /**
     * 根据ID获取站点详情
     */
    @GetMapping("/{id}")
    public Result<Station> getStationById(@PathVariable Integer id) {
        try {
            return stationRepository.findById(id)
                    .map(station -> {
                        // 填充管理员名称和电话
                        if (station.getManagerId() != null) {
                            userRepository.findById(station.getManagerId()).ifPresent(user -> {
                                station.setManagerName(user.getRealName());
                                station.setManagerPhone(user.getPhone());
                            });
                        }
                        return Result.success(station);
                    })
                    .orElse(Result.error("站点不存在"));
        } catch (Exception e) {
            logger.error("获取站点详情失败", e);
            return Result.error("获取站点详情失败");
        }
    }
    
    /**
     * 获取站点负载统计
     */
    @GetMapping("/{id}/load-stats")
    public Result<Map<String, Object>> getStationLoadStats(@PathVariable Integer id) {
        try {
            // 验证站点是否存在
            Station station = stationRepository.findById(id)
                    .orElseThrow(() -> new RuntimeException("站点不存在"));
            
            Map<String, Object> stats = new HashMap<>();
            
            // 1. 总订单数 - 该站点的所有订单
            Long totalOrders = orderRepository.countByStationId(id);
            stats.put("totalOrders", totalOrders);
            
            // 2. 总收益 - 已完成订单的总金额
            BigDecimal totalRevenue = orderRepository.sumTotalAmountByStationIdAndStatus(
                    id, Order.OrderStatus.completed);
            stats.put("totalRevenue", totalRevenue != null ? totalRevenue.doubleValue() : 0.0);
            
            // 3. 总重量 - 从库存中计算
            Double totalWeight = stationInventoryRepository.findByStationId(id).stream()
                    .mapToDouble(inv -> inv.getQuantity().doubleValue())
                    .sum();
            stats.put("totalWeight", totalWeight);
            
            // 4. 客户数量 - 在该站点下单的不同客户数
            Long customerCount = orderRepository.countDistinctCustomersByStationId(id);
            stats.put("customerCount", customerCount);
            
            // 5. 利用率 - 当前负载/容量 * 100
            Double utilizationRate = 0.0;
            if (station.getCapacity() != null && station.getCapacity().doubleValue() > 0) {
                utilizationRate = (station.getCurrentLoad().doubleValue() / station.getCapacity().doubleValue()) * 100;
            }
            stats.put("utilizationRate", Math.round(utilizationRate * 100.0) / 100.0);
            
            return Result.success(stats);
        } catch (Exception e) {
            logger.error("获取站点负载统计失败", e);
            return Result.error("获取站点负载统计失败: " + e.getMessage());
        }
    }

    /**
     * 创建站点
     */
    @PostMapping
    public Result<Station> createStation(@RequestBody Station station) {
        try {
            // 检查站点名称是否已存在
            if (stationRepository.existsByName(station.getName())) {
                return Result.error("站点名称已存在");
            }

            // 设置默认状态和负载
            if (station.getStatus() == null) {
                station.setStatus(Station.StationStatus.active);
            }
            if (station.getCurrentLoad() == null) {
                station.setCurrentLoad(0);
            }

            Station savedStation = stationRepository.save(station);
            return Result.success("站点创建成功", savedStation);
        } catch (Exception e) {
            logger.error("创建站点失败", e);
            return Result.error("创建站点失败");
        }
    }

    /**
     * 更新站点信息
     */
    @PutMapping("/{id}")
    public Result<Station> updateStation(@PathVariable Integer id, @RequestBody Station station) {
        try {
            return stationRepository.findById(id)
                    .map(existingStation -> {
                        // 检查名称是否与其他站点重复
                        if (!existingStation.getName().equals(station.getName()) &&
                            stationRepository.existsByName(station.getName())) {
                            return Result.<Station>error("站点名称已存在");
                        }

                        // 更新字段
                        existingStation.setName(station.getName());
                        existingStation.setAddress(station.getAddress());
                        existingStation.setLatitude(station.getLatitude());
                        existingStation.setLongitude(station.getLongitude());
                        existingStation.setContactPhone(station.getContactPhone());
                        existingStation.setCapacity(station.getCapacity());
                        if (station.getManagerId() != null) {
                            existingStation.setManagerId(station.getManagerId());
                        }

                        Station updatedStation = stationRepository.save(existingStation);
                        return Result.success("站点更新成功", updatedStation);
                    })
                    .orElse(Result.error("站点不存在"));
        } catch (Exception e) {
            logger.error("更新站点失败", e);
            return Result.error("更新站点失败");
        }
    }

    /**
     * 删除站点
     */
    @DeleteMapping("/{id}")
    public Result<String> deleteStation(@PathVariable Integer id) {
        try {
            if (!stationRepository.existsById(id)) {
                return Result.error("站点不存在");
            }

            stationRepository.deleteById(id);
            return Result.success("站点删除成功", "删除成功");
        } catch (Exception e) {
            logger.error("删除站点失败", e);
            return Result.error("删除站点失败");
        }
    }

    /**
     * 批量删除站点
     */
    @DeleteMapping("/batch")
    public Result<String> batchDeleteStations(@RequestBody Map<String, List<Integer>> request) {
        try {
            List<Integer> stationIds = request.get("stationIds");
            if (stationIds == null || stationIds.isEmpty()) {
                return Result.error("请提供要删除的站点ID列表");
            }

            stationRepository.deleteAllById(stationIds);
            return Result.success("批量删除成功", "删除成功");
        } catch (Exception e) {
            logger.error("批量删除站点失败", e);
            return Result.error("批量删除站点失败");
        }
    }

    /**
     * 更新站点状态
     */
    @PatchMapping("/{id}/status")
    public Result<Station> updateStationStatus(@PathVariable Integer id, @RequestBody Map<String, String> request) {
        try {
            String statusStr = request.get("status");
            if (statusStr == null) {
                return Result.error("状态参数缺失");
            }

            Station.StationStatus newStatus;
            try {
                newStatus = Station.StationStatus.valueOf(statusStr);
            } catch (IllegalArgumentException e) {
                return Result.error("无效的状态值");
            }

            return stationRepository.findById(id)
                    .map(station -> {
                        station.setStatus(newStatus);
                        Station updatedStation = stationRepository.save(station);
                        return Result.success("状态更新成功", updatedStation);
                    })
                    .orElse(Result.error("站点不存在"));
        } catch (Exception e) {
            logger.error("更新站点状态失败", e);
            return Result.error("更新站点状态失败");
        }
    }

    /**
     * 分配管理员到站点
     */
    @PatchMapping("/{id}/manager")
    public Result<Station> assignManager(@PathVariable Integer id, @RequestBody Map<String, Integer> request) {
        try {
            Integer managerId = request.get("managerId");
            if (managerId == null) {
                return Result.error("管理员ID参数缺失");
            }

            // 验证管理员是否存在
            User manager = userRepository.findById(managerId)
                    .orElseThrow(() -> new RuntimeException("管理员不存在"));

            // 验证用户角色是否为站点管理员
            if (!"station_manager".equals(manager.getRole())) {
                return Result.error("该用户不是站点管理员");
            }

            return stationRepository.findById(id)
                    .map(station -> {
                        station.setManagerId(managerId);
                        Station updatedStation = stationRepository.save(station);
                        return Result.success("分配管理员成功", updatedStation);
                    })
                    .orElse(Result.error("站点不存在"));
        } catch (Exception e) {
            logger.error("分配管理员失败", e);
            return Result.error("分配管理员失败: " + e.getMessage());
        }
    }

    /**
     * 取消站点管理员分配
     */
    @DeleteMapping("/{id}/manager")
    public Result<Station> unassignManager(@PathVariable Integer id) {
        try {
            return stationRepository.findById(id)
                    .map(station -> {
                        station.setManagerId(null);
                        Station updatedStation = stationRepository.save(station);
                        return Result.success("取消分配成功", updatedStation);
                    })
                    .orElse(Result.error("站点不存在"));
        } catch (Exception e) {
            logger.error("取消分配管理员失败", e);
            return Result.error("取消分配管理员失败");
        }
    }

    /**
     * 获取可用站点列表（用于客户下单选择）
     */
    @GetMapping("/available")
    public Result<List<Station>> getAvailableStations() {
        try {
            // 获取所有活跃状态的站点
            List<Station> availableStations = stationRepository.findByStatus(
                Station.StationStatus.active, 
                Pageable.unpaged()
            ).getContent();
            
            // 填充管理员信息
            for (Station station : availableStations) {
                if (station.getManagerId() != null) {
                    userRepository.findById(station.getManagerId()).ifPresent(user -> {
                        station.setManagerName(user.getRealName());
                        station.setManagerPhone(user.getPhone());
                    });
                }
            }
            
            return Result.success(availableStations);
        } catch (Exception e) {
            logger.error("获取可用站点列表失败", e);
            return Result.error("获取可用站点列表失败");
        }
    }

    /**
     * 获取站点统计信息
     */
    @GetMapping("/stats")
    public Result<Map<String, Object>> getStationStats() {
        try {
            long totalStations = stationRepository.count();
            long activeStations = stationRepository.findByStatus(Station.StationStatus.active, Pageable.unpaged()).getTotalElements();
            long busyStations = stationRepository.findByStatus(Station.StationStatus.busy, Pageable.unpaged()).getTotalElements();
            long closedStations = stationRepository.findByStatus(Station.StationStatus.closed, Pageable.unpaged()).getTotalElements();

            Map<String, Object> stats = new HashMap<>();
            stats.put("totalStations", totalStations);
            stats.put("activeStations", activeStations);
            stats.put("busyStations", busyStations);
            stats.put("closedStations", closedStations);

            return Result.success(stats);
        } catch (Exception e) {
            logger.error("获取站点统计失败", e);
            return Result.error("获取站点统计失败");
        }
    }

    /**
     * 获取站点库存列表
     */
    @GetMapping("/{stationId}/inventory")
    public Result<Map<String, Object>> getStationInventory(
            @PathVariable Integer stationId,
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "10") Integer pageSize,
            @RequestParam(required = false) String category,
            @RequestParam(required = false) String keyword,
            @RequestParam(required = false) Long _t) {  // 时间戳参数，用于防止缓存
        try {
            // 使用原生SQL查询，避免JPA缓存
            List<StationInventory> inventoryList = stationInventoryRepository.findByStationIdNative(stationId);
            
            // 转换为VO并应用过滤条件
            List<StationInventoryVO> voList = new ArrayList<>();
            for (StationInventory inventory : inventoryList) {
                StationInventoryVO vo = StationInventoryVO.fromEntity(inventory);
                
                // 应用过滤条件
                boolean matchesCategory = category == null || category.isEmpty() || 
                                        (vo.getCategory() != null && vo.getCategory().equals(category));
                boolean matchesKeyword = keyword == null || keyword.isEmpty() || 
                                       (vo.getItemName() != null && vo.getItemName().contains(keyword));
                
                if (matchesCategory && matchesKeyword) {
                    voList.add(vo);
                }
            }

            // 手动分页
            int start = (page - 1) * pageSize;
            int end = Math.min(start + pageSize, voList.size());
            List<StationInventoryVO> pagedList = start < voList.size() ? voList.subList(start, end) : new ArrayList<>();

            Map<String, Object> result = new HashMap<>();
            result.put("list", pagedList);
            result.put("total", voList.size());
            result.put("page", page);
            result.put("pageSize", pageSize);

            return Result.success(result);
        } catch (Exception e) {
            logger.error("获取站点库存失败", e);
            return Result.error("获取站点库存失败: " + e.getMessage());
        }
    }

    /**
     * 更新/添加站点库存
     */
    @PutMapping("/{stationId}/inventory")
    public Result<String> updateStationInventory(
            @PathVariable Integer stationId,
            @RequestBody Map<String, Object> request) {
        try {
            Integer itemId = (Integer) request.get("itemId");
            String type = (String) request.get("type");  // add, reduce, set
            Object quantityObj = request.get("quantity");
            Object minStockObj = request.get("minStock");
            Object maxStockObj = request.get("maxStock");
            String reason = (String) request.get("reason");

            if (itemId == null || quantityObj == null) {
                return Result.error("参数缺失");
            }

            BigDecimal quantity = new BigDecimal(quantityObj.toString());

            // 查找或创建库存记录
            StationInventory inventory = stationInventoryRepository
                    .findByStationIdAndItemId(stationId, itemId)
                    .orElseGet(() -> {
                        StationInventory newInventory = new StationInventory();
                        newInventory.setStationId(stationId);
                        newInventory.setItemId(itemId);
                        newInventory.setQuantity(BigDecimal.ZERO);
                        newInventory.setMinStock(BigDecimal.valueOf(10));
                        newInventory.setMaxStock(BigDecimal.valueOf(100));
                        return newInventory;
                    });

            BigDecimal beforeQuantity = inventory.getQuantity();
            BigDecimal afterQuantity;
            BigDecimal changeQuantity;

            // 根据类型计算新库存
            if ("add".equals(type)) {
                afterQuantity = beforeQuantity.add(quantity);
                changeQuantity = quantity;
            } else if ("reduce".equals(type)) {
                afterQuantity = beforeQuantity.subtract(quantity);
                changeQuantity = quantity.negate();
            } else if ("set".equals(type)) {
                afterQuantity = quantity;
                changeQuantity = quantity.subtract(beforeQuantity);
            } else {
                // 默认为设置库存
                afterQuantity = quantity;
                changeQuantity = quantity.subtract(beforeQuantity);
            }

            // 确保库存不为负
            if (afterQuantity.compareTo(BigDecimal.ZERO) < 0) {
                return Result.error("库存不能为负数");
            }

            // 更新库存数量
            inventory.setQuantity(afterQuantity);
            
            // 更新最低/最高库存（如果提供了的话）
            if (minStockObj != null) {
                inventory.setMinStock(new BigDecimal(minStockObj.toString()));
            }
            if (maxStockObj != null) {
                inventory.setMaxStock(new BigDecimal(maxStockObj.toString()));
            }
            
            stationInventoryRepository.save(inventory);
            
            logger.info("库存更新成功: stationId={}, itemId={}, beforeQuantity={}, afterQuantity={}", 
                        stationId, itemId, beforeQuantity, afterQuantity);

            // 记录库存历史
            InventoryHistory history = new InventoryHistory();
            history.setStationId(stationId);
            history.setItemId(itemId);
            history.setOperationType(type != null ? type : "adjust");
            history.setBeforeQuantity(beforeQuantity);
            history.setChangeQuantity(changeQuantity);
            history.setAfterQuantity(afterQuantity);
            history.setReason(reason != null ? reason : "手动调整");
            history.setOperator("系统管理员");  // TODO: 从当前登录用户获取
            inventoryHistoryRepository.save(history);

            // 更新站点的当前负载
            updateStationLoad(stationId);

            return Result.success("库存更新成功", "操作成功");
        } catch (Exception e) {
            logger.error("更新站点库存失败", e);
            return Result.error("更新站点库存失败: " + e.getMessage());
        }
    }

    /**
     * 删除站点库存
     */
    @DeleteMapping("/{stationId}/inventory/{itemId}")
    public Result<String> deleteStationInventory(
            @PathVariable Integer stationId,
            @PathVariable Integer itemId) {
        try {
            // 查找库存记录
            StationInventory inventory = stationInventoryRepository
                    .findByStationIdAndItemId(stationId, itemId)
                    .orElseThrow(() -> new RuntimeException("库存记录不存在"));

            // 删除库存记录
            stationInventoryRepository.delete(inventory);

            // 删除相关的历史记录（可选，根据业务需求决定是否保留历史）
            // inventoryHistoryRepository.deleteByStationIdAndItemId(stationId, itemId);

            // 更新站点的当前负载
            updateStationLoad(stationId);

            return Result.success("库存删除成功", "删除成功");
        } catch (Exception e) {
            logger.error("删除站点库存失败", e);
            return Result.error("删除站点库存失败: " + e.getMessage());
        }
    }

    /**
     * 获取库存历史
     */
    @GetMapping("/{stationId}/inventory/{itemId}/history")
    public Result<List<InventoryHistoryVO>> getInventoryHistory(
            @PathVariable Integer stationId,
            @PathVariable Integer itemId) {
        try {
            List<InventoryHistory> historyList = inventoryHistoryRepository
                    .findByStationIdAndItemIdOrderByCreatedAtDesc(stationId, itemId);

            List<InventoryHistoryVO> voList = historyList.stream()
                    .map(InventoryHistoryVO::fromEntity)
                    .collect(Collectors.toList());

            return Result.success(voList);
        } catch (Exception e) {
            logger.error("获取库存历史失败", e);
            return Result.error("获取库存历史失败: " + e.getMessage());
        }
    }

    /**
     * 更新站点的当前负载
     */
    private void updateStationLoad(Integer stationId) {
        try {
            List<StationInventory> inventoryList = stationInventoryRepository.findByStationId(stationId);
            BigDecimal totalLoad = inventoryList.stream()
                    .map(StationInventory::getQuantity)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);

            stationRepository.findById(stationId).ifPresent(station -> {
                station.setCurrentLoad(totalLoad.intValue());
                stationRepository.save(station);
            });
        } catch (Exception e) {
            logger.error("更新站点负载失败", e);
        }
    }
}

